home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Workspace / AltDock / Source / MyApp.m < prev    next >
Text File  |  1995-06-12  |  7KB  |  246 lines

  1.  
  2. /* MyApp.m */
  3.  
  4. #import <objc/List.h>
  5. #import <appkit/Window.h>
  6. #import <appkit/Bitmap.h>
  7. #import <appkit/Listener.h>
  8. #import <appkit/Bitmap.h>
  9. #import <appkit/graphics.h>
  10. #import <dpsclient/psops.h>
  11. #import <dpsclient/wraps.h>
  12. #import <streams/streams.h>
  13. #import <libc.h>
  14. #import <strings.h>
  15. #import <pwd.h>
  16. #import "IconView.h"
  17. #import "DockSpeaker.h"
  18. #import "MyApp.h"
  19.  
  20.  
  21. #define READ 0
  22. #define DOCK_WINDOW_LEVEL (NX_MAINMENULEVEL - 1)
  23.  
  24. char *mySalloc(string)
  25. /* returns a copy of string */
  26. char *string;
  27. {
  28.     char *newString;
  29.     
  30.     newString = (char *)malloc(strlen(string) + 1);
  31.     if (!newString) {
  32.       return("");
  33.     }
  34.     strcpy(newString, string);
  35.     return newString;
  36. }
  37.  
  38. @implementation MyApp
  39.  
  40. /* factory methods */
  41.  
  42. + new
  43. {
  44.     self = [super new];
  45.     
  46.     /* we want to be our own delegate */
  47.     [self setDelegate:self];
  48.     
  49.     return self;
  50. }
  51.  
  52.  
  53. /* class methods */
  54.  
  55. - createDockWindows:(int *)minX :(int *)minY :(int *)maxX :(int *)maxY
  56. /* creates the dock windows based on the .altdock file */
  57. {
  58.     id           dockWindowList, appBitmap;
  59.     NXStream       *fileStream;
  60.     int           fd, scanResult, success, xCoordinate, yCoordinate;
  61.     char       *homeDir, *dockFile, *appFileName;
  62.     struct passwd  *passwdEntry;
  63.     
  64.     /* initialize the bounding box */
  65.     *minX = *minY = *maxX = *maxY = 0;
  66.     
  67.     /* create a list to hold the dock's windows */
  68.     dockWindowList = [List new];
  69.     
  70.     /* get ready to ask the WorkSpace for icons */
  71.     [[self appSpeaker] setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)];
  72.  
  73.     /* get the user's home directory and create the .altdock file's abs path */
  74.     passwdEntry = getpwuid((int)getuid());
  75.     homeDir = passwdEntry->pw_dir;
  76.     dockFile = (char *)malloc(strlen(homeDir) + 10);
  77.     sprintf(dockFile, "%s/.altdock", homeDir);
  78.     
  79.     /* open a stream on the .altdock file */
  80.     fd = open(dockFile, READ);
  81.     if (fd < 0) {
  82.       NXRunAlertPanel(NULL, "Couldn't open .altdock file", NULL, NULL, NULL);
  83.       free(dockFile);
  84.       return dockWindowList;
  85.     }
  86.     fileStream = NXOpenFile(fd, NX_READONLY);
  87.  
  88.     while (YES) {
  89.       /* get the window's x and y coordinates, then the app's path */
  90.       scanResult = NXScanf(fileStream, "%d %d\n", &xCoordinate, &yCoordinate);
  91.       if (scanResult == EOF) {
  92.         break;
  93.       } else if (scanResult < 2) {
  94.         NXRunAlertPanel(NULL, "Error reading .altdock file", NULL, NULL, NULL);
  95.     break;
  96.       }
  97.       appFileName = [self stringFromStream:fileStream ok:&success];
  98.       if (!success) {
  99.         /* we've reached the end of the .altdock file */
  100.         NXRunAlertPanel(NULL, "Error reading .altdock file", NULL, NULL, NULL);
  101.         break;
  102.       }
  103.       
  104.       /* get the app's bitmap */
  105.       appBitmap = [self bitmapFor:appFileName];
  106.       
  107.       /* create the window */
  108.       [dockWindowList addObject:[self newIconWindowFor:appBitmap
  109.                                     :xCoordinate
  110.                               :yCoordinate
  111.                               :appFileName]];
  112.       /* adjust the bounding box */
  113.       if (xCoordinate < *minX) *minX = xCoordinate;
  114.       if (yCoordinate < *minY) *minY = yCoordinate;
  115.       if (xCoordinate > *maxX) *maxX = xCoordinate;
  116.       if (yCoordinate > *maxY) *maxY = yCoordinate;
  117.       free(appFileName);
  118.     }
  119.     
  120.     /* clean up */
  121.     NXClose(fileStream);
  122.     free(dockFile);
  123.     
  124.     return dockWindowList;
  125. }
  126.  
  127. - bitmapFor:(char *)appFileName
  128. {
  129.     id        bitmap;
  130.     char      tiffDataBuffer[3000], *tiffDataBufferPtr;
  131.     int       length, flag;
  132.     NXStream  *tiffDataStream;
  133.     
  134.     if (!strcmp("Dock", appFileName)) {
  135.       /* assign the dock window's bitmap */
  136.       bitmap = [Bitmap findBitmapFor:"TXeN"];
  137.     } else {
  138.       /* ask the WorkSpace for the app's bitmap */
  139.       tiffDataBufferPtr = tiffDataBuffer;
  140.       [[self appSpeaker] getFileIconFor:appFileName
  141.              TIFF:&tiffDataBufferPtr
  142.              TIFFLength:&length
  143.              ok:&flag];
  144.       /* get a stream on memory buffer holding the TIFF data */
  145.       tiffDataStream = NXOpenMemory(tiffDataBufferPtr, length, NX_READONLY);
  146.       bitmap = [Bitmap newFromStream:tiffDataStream];
  147.       NXClose(tiffDataStream);
  148.     }
  149.  
  150.     return bitmap;
  151. }
  152.  
  153. - newIconWindowFor:bitmap :(int)xCoord :(int)yCoord :(char *)applicationName
  154. {
  155.     NXRect  windowRect;
  156.     id      iconWindow, iconView;
  157.     
  158.     /* compute the new window's screen location */
  159.     windowRect.origin.x = 4.0 + 64.0 * xCoord;
  160.     windowRect.origin.y = 0.0 + 64.0 * yCoord;
  161.     windowRect.size.height = windowRect.size.width = 64.0;
  162.     
  163.     /* create a new window */
  164.     iconWindow = [Window newContent:&windowRect
  165.                  style:NX_PLAINSTYLE
  166.              backing:NX_BUFFERED
  167.              buttonMask:0
  168.              defer:YES];
  169.  
  170.     /* create an iconView to go in this window */         
  171.     iconView = [IconView new:applicationName :bitmap :xCoord :yCoord];
  172.     
  173.     /* stick the iconView in the window */
  174.     [iconWindow setContentView:iconView];
  175.     
  176.     /* make the view the window's delegate and first responder */
  177.     [iconWindow setDelegate:iconView];
  178.     [iconWindow makeFirstResponder:iconView];
  179.     
  180.     /* create the PostScript window and stick it in the screen list */
  181.     [iconWindow makeKeyAndOrderFront:self];
  182.  
  183.     /* set the window's level in the screen list to be just below menus */
  184.     _NXSetWindowLevel([iconWindow windowNum], DOCK_WINDOW_LEVEL);
  185.     
  186.     return iconWindow;
  187. }
  188.  
  189. - (char *)stringFromStream:(NXStream *)fileStream ok:(int *)success
  190. /* reads a newline-terminated string from a stream */
  191. {
  192.     char   stringBuffer[1024];
  193.     int    nextChar, characterNumber = 0;
  194.  
  195.     while ((nextChar = NXGetc(fileStream)) != '\n') {
  196.       /* make sure we haven't reached the end of the file */
  197.       if (nextChar == EOF) {
  198.         *success = 0;
  199.     return "";
  200.       }
  201.       stringBuffer[characterNumber++] = (char)nextChar;
  202.     }
  203.     stringBuffer[characterNumber] = '\0';
  204.     *success = 1;
  205.  
  206.     /* create space for the string, copy it, and return the new string */
  207.     return mySalloc(stringBuffer);
  208. }
  209.  
  210.  
  211. /* delegation methods */
  212.  
  213. - appDidInit:sender
  214. {
  215.     id     dockWindowList, dockWindow;
  216.     int    minX, minY, maxX, maxY, i;
  217.     
  218.     /* we need to use our own special Speaker class object */
  219.     [self setAppSpeaker:[DockSpeaker new]];
  220.     
  221.     /* create the dock's windows */
  222.     dockWindowList = [self createDockWindows:&minX :&minY :&maxX :&maxY];
  223.  
  224.     /* find the dock window (the one with the backward NeXT) */
  225.     i = [dockWindowList count];
  226.     while (i--) {
  227.       dockWindow = [dockWindowList objectAt:i];
  228.       if ([[dockWindow contentView] theDock]) {
  229.         break;
  230.       }
  231.     }
  232.     
  233.     if ([[dockWindow contentView] theDock]) {
  234.       /* give the dock window the bounding box of all of the windows */
  235.       [[dockWindow contentView] initialize:dockWindowList
  236.                             :minX
  237.                       :minY
  238.                       :maxX
  239.                       :maxY];
  240.     }
  241.     
  242.     return self;
  243. }
  244.  
  245. @end
  246.